package tests.experiments.moore;

import jeconbond.automata.INode;
import jeconbond.automata.IOutcome;
import jeconbond.automata.AutomataUtils;
import jeconbond.economic.resources.IResourceType;
import jeconbond.economic.resources.ResourceStorrage;
import jeconbond.economic.resources.ResourceUtils;
import jeconbond.economic.systems.market.DefaultMarketRRSFactory;
import jeconbond.experiment.market.equilibrium.MooreExperimentSettings;
import jeconbond.experiment.market.equilibrium.generate.MooreAutomataGenerator;
import jeconbond.experiment.JEBExperimentFlow;
import jeconbond.experiment.generate.ProfitableNormFormGenerateDecorator;
import jeconbond.experiment.process.IJEBExperimentContext;
import junit.framework.Assert;
import junit.framework.TestCase;

import laboratoryQ.experiment.IExperiment;
import laboratoryQ.flatness.Point;

import java.util.List;

public class TestEasyEquilibrium extends TestCase {
	private static final IExperiment EXPERIMENT = new JEBExperimentFlow();

	public void testEasygenerator() {
		MooreExperimentSettings settings = 
			new MooreExperimentSettings();
		settings.initialise();
		
		settings.stepSize = 20;
		settings.stepCount = 50;
		settings.agentsCount = 2;
		settings.chainLength = 2;
		settings.produceProfit = 1.123;
		settings.initResourceExceedPercent = 1.1;
		settings.purchaseExceedPassivePeriod = settings.chainLength * 3;
		settings.agentGreedPercent = 2.5;
		settings.initMoney = 10.0;
		settings.observeCostsTraceLength = 10;
		settings.concurrentPricePercent = 0.0;
		settings.utiliseExceedPeriod = -2.0;
		
		settings.rrsFactory = new DefaultMarketRRSFactory();
		settings.resources = ResourceUtils.generateResources("r", 9);
		settings.utiliseExceedPeriod = -2.0;
		settings.purchaseExceedDayBudget = -2.0;
		settings.purchaseExceedUseTrackLength = -2;
		settings.experiment = EXPERIMENT;
		settings.randomSeed = 0.0;
		settings.zeroPoint = new Point(0.0, 0.0);
		settings.selectPropositionsPart = -1;
		settings.profitCostManagerFactory = MooreAutomataGenerator.MANAGER_FACTORY_INSTANCE;
		settings.validate();
		
		IJEBExperimentContext context = (IJEBExperimentContext)
				settings.getExperimentContextFactory().newContext(settings); 
		INode[] automatas = generate(context);
		Assert.assertEquals(settings.agentsCount, automatas.length);
		List<IOutcome> trace = AutomataUtils.easyTracePlan(automatas[0]);
		Assert.assertEquals(settings.chainLength, trace.size());
		ResourceStorrage costs = new ResourceStorrage();
		ResourceStorrage profit = new ResourceStorrage();
		for (int i = 0; i < settings.agentsCount; i++) {
			AutomataUtils.dfsCosts(automatas[i], costs, profit);
		}
		for (IResourceType rt : settings.resources) {
			double c = costs.howMuchWasStored(rt);
			double p = profit.howMuchWasStored(rt);
			Assert.assertTrue(Math.abs(settings.produceProfit - p / c) < 1e-5);
		}
	}

	private INode[] generate(IJEBExperimentContext context) {
		return new ProfitableNormFormGenerateDecorator(new MooreAutomataGenerator()).generate(context);
	}
}
